package com.apobates.forum.toro.proxy.strategy;

import com.apobates.forum.toro.proxy.MapperMultiAttrExpression;
import com.apobates.forum.toro.proxy.MapperMultiAttrStatements;
import com.apobates.forum.toro.utils.BeanHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

public class MapperParallelManyStrategy<E> extends AbstractProxyStrategy<E> implements MapperManyStrategy<E>{
    private static final Logger logger = LoggerFactory.getLogger(MapperParallelManyStrategy.class);
    @Override
    public void consumer(Set<MapperMultiAttrExpression> selectExprSet, Collection<E> targetObjSet, Map<String, Set<String>> batchQueryArgs) {
        logger.debug("[MSMS][ParallelMany]many parallel strategy start");
        // 4)构造后续操作的数据集
        final Function<MapperMultiAttrExpression,String> rawKeyFun = (mmas) ->mmas.getTargetAttr();
        final Function<MapperMultiAttrExpression,Collection<Object>> rawValFun = (mmas)-> {
            return mmas.getQueryFace().query(batchQueryArgs.get(mmas.getTargetAttr()));
        };
        // 获取数据源(key=设置目标的属性名, value候选的关联对象集合)
        final Map<String, Collection<Object>> rawSource = selectExprSet.stream().parallel().collect(Collectors.toMap(rawKeyFun, rawValFun));
        final Map<String, MapperMultiAttrStatements.Argument> selectAttrMap = selectExprSet
                .stream()
                .collect(Collectors.toMap(muaem->muaem.getSelectAttr(), muaem->muaem.buildRelationArgs()));
        /* 设置关联对象 */
        final Consumer<E> composeFun = (targetObj)->{
            // 2)收集需要批量设置的属性值.为下一步批量设置准备数量
            Map<String,Object> setAttrValMap = this.collectRelateObj(targetObj, selectAttrMap, rawSource);
            // 1)批量设置组合的关联对象
            try {
                BeanHelper.setMultiAttrVal(targetObj, setAttrValMap);
            }catch (Exception e){
                String bb = "[MSMS][ParallelMany]batch set attrVal fail,error:"+e.getMessage();
                System.out.println(bb);
                // logger.debug(bb);
            }
        };
        targetObjSet.stream().parallel().forEach(composeFun);
    }

    @Override
    protected String getSentinel() {
        return "ParallelMany";
    }
}
